package org.liziyi.pss.model.queue;

import org.liziyi.pss.common.enums.ProcessAttributeEnum;
import org.liziyi.pss.entity.ProcessControlBlock;
import org.liziyi.pss.util.ProcessUtil;

import javax.swing.*;
import javax.swing.table.TableModel;
import java.util.HashSet;

/**
 * 后备队列
 *·
 * @author liziyi
 */
public class BackUpQueue extends AbstractScheduleQueue{
    /**
     * 用于存放已经执行完成的进程的PID。在从后备队列中取出同步进程时，需要确定其前驱进程是否已经执行完毕
     */
    private final HashSet<Integer> finishedPidSet;
    public BackUpQueue(TableModel model){
        super(model);
        finishedPidSet=new HashSet<>();
    }

    @Override
    public synchronized ProcessControlBlock poll() {
        ProcessControlBlock pcb;
        for(int i=0;i<queueList.size();i++){
            pcb=queueList.get(i);
            // 独立进程直接返回
            if(pcb.getAttribute().equals(ProcessAttributeEnum.NORMAL_PROCESS.getDesc())){
               return super.remove(i);
            } else{
                // 取出前驱pid   同步进程(%d/%d)
                int prePid=Integer.parseInt(pcb.getAttribute().split("\\(")[1].split("/")[0]);
                if(prePid==-1 || finishedPidSet.contains(prePid)){
                    return super.remove(i);
                }
            }
        }
        return null;
    }
    @Override
    public synchronized void add(ProcessControlBlock pcb) {
        if(queueList.isEmpty()){
            super.add(pcb);
            return;
        }
        for(int i=0;i<queueList.size();i++){
            if(queueList.get(i).getPriority()>pcb.getPriority()){
                queueList.add(i,pcb);
                int ti=i;
                SwingUtilities.invokeLater(()->{
                    queueTableModel.insertRow(ti, ProcessUtil.pcb2TableRow(pcb));
                });
                return;
            }
        }
        super.add(pcb);
    }

    public synchronized void addFinishedPid(int pid){
        finishedPidSet.add(pid);
    }
}
